# `TransferPolicyTransaction`

`TransferPolicyTransaction` is the client to build transactions that involve transfer policy
management. It's used similar to `KioskTransaction`, and helps in crafting transactions to manage a
transfer policy.

You need to instantiate it once in every Programmable Transaction Block (PTB) that you're building.

Similar to `KioskTransaction`, you can either create a new transfer policy, or use an existing one.

## Using an existing transfer policy

If you have already retrieved a transfer policy from `kioskClient.getOwnedTransferPolicies()`, or
`kioskClient.getOwnedTransferPoliciesByType()`, you can pass a `TransferPolicyCap` result when
instantiating.

```typescript
// Initialized somewhere in the app.
const kioskClient = new KioskClient({...});

// You could have more than one cap, since we can create more than one transfer policy.
const heroPolicyCaps = await kioskClient.getOwnedTransferPoliciesByType({
    type: `${packageId}::hero::Hero`,
    address: '0xConnectedAddress',
});

const tx = new Transaction();
// You can choose to use any of the caps you have. For this example, use the first one.
const tpTx = new TransferPolicyTransaction({ kioskClient, transaction: tx, cap: heroPolicyCaps[0] });

// A demonstration of using all the available rule add/remove functions.
// You can chain these commands.
tpTx
    .addFloorPriceRule(10n)
    .addLockRule()
    .addRoyaltyRule(percentageToBasisPoints(10), 0)
    .addPersonalKioskRule()
    // .removeFloorPriceRule()
    // .removeLockRule()
    // .removeRoyaltyRule()
    // .removePersonalKioskRule()

// Sign and execute transaction.
await signAndExecuteTransaction({tx: tx});
```

## Creating a new transfer policy

If you don't have an existing transfer policy, you can create a new one. You can also attach rules
in the same PTB.

```typescript
const publisher = '0xPackagePublisherObject';
const tx = new Transaction();

const tpTx = new TransferPolicyTransaction({ kioskClient, transaction: tx });

// This is an async call, as the SDK protects from accidentally creating
// a second transfer policy.
// You can skip this check by passing `skipCheck: true`.
await tpTx.create({
	type: `${heroPackageId}::hero::Hero`,
	publisher,
});

tpTx
	.addLockRule()
	.addFloorPriceRule(1000n)
	.addRoyaltyRule(percentageToBasisPoints(10), 100)
	.addPersonalKioskRule()
	// Transfers the `TransferPolicyCap` to the user and shares the transfer policy.
	.shareAndTransferCap('address_to_transfer_cap_to');

// Sign and execute transaction.
await signAndExecuteTransaction({ tx: tx });
```
